<?php

class Application_Model_DomainObject {

    protected $_dbTable;
    protected $_tableName;

    /**
     * 构造方法，初始化对象，并默认设置持久化操作类
     * 如果$options类型是array,则用array中的值初始化对象
     * 如果$options类型为数字,则试该参数为ID，并用此ID重建该对象
     * @param array $options
     */
    public function __construct($options = null) {
        $ref = get_class($this);
        $this->_tableName = str_replace('Application_Model_', 'Application_Model_DbTable_', $ref);

        if (is_array($options)) {
            $this->setOptions($options);
        } else if (is_numeric($options)) {
            $this->getDbTable()->setById($this, $options);
        }
    }

    /**
     * 用魔术方法模拟出类似 $object->Property 的操作方法。
     * 如果定义了setProperty,优先使用set方法设值,如果没有，则直接给_property变量的设值
     * @param unknown_type $name
     * @param unknown_type $value
     * @throws Exception
     */
    public function __set($name, $value) {
        $method = 'set' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            $prop = '_' . $this->lcfirstex($name);
            if (property_exists($this, $prop)) {
                $this->$prop = $value;
                return;
            } else
                throw new Exception('设置了不存在的属性，请检查:' . $name);
        }
        $this->$method($value);
    }

    /**
     * 用魔术方法模拟出类似 $object->Property 的操作方法。
     * 如果定义了getProperty,优先使用get方法返回,如果没有，则直接返回_property变量的值
     * @param unknown_type $name
     * @throws Exception
     */
    public function __get($name) {
        $method = 'get' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            $prop = '_' . $this->lcfirstex($name);
            if (property_exists($this, $prop))
                return $this->$prop;
            else
                throw new Exception('获取了不存在的属性，请检查:' . $name);
        }
        return $this->$method();
    }

    /**
     * 用指定的值初始化对象
     * @param array $options
     * @return Application_Model_DomainObject
     */
    public function setOptions(array $options) {
        $mapper = $this->getDbTable()->getMapper();
        foreach ($options as $key => $value) {
            if (in_array($key, $mapper) || in_array($this->lcfirstex($key), $mapper)) {
                $method = ucfirst($key);
                $this->$method = $value;
            }
        }
        return $this;
    }

    /**
     * 设置对象的持久化操作类
     * @param string|Application_Model_DbTable_DomainObject $dbTable
     * @throws Exception
     */
    public function setDbTable($dbTable) {
        if (is_string($dbTable)) {
            $dbTable = new $dbTable();
        }

        if (!$dbTable instanceof Zend_Db_Table_Abstract) {
            throw new Exception('Invalid table data gateway provided');
        }

        $this->_dbTable = $dbTable;
        return $this;
    }

    /**
     * 返回一个操作
     * @return Application_Model_DbTable_DomainObject
     */
    public function getDbTable() {
        if (null === $this->_dbTable) {
            $this->setDbTable($this->_tableName);
        }
        return $this->_dbTable;
    }

    /**
     * 保存对对象的修改，如果有ID，则Updadte，如果没有ID，则新增一个对象
     * @return Application_Model_DomainObject
     */
    public function save() {
        return $this->getDbTable()->save($this);
    }

    public function editupdate() {
        return $this->getDbTable()->editupdate($this);
    }

    /**
     * 新增对像 
     */
    public function insertId() {
        $this->getDbTable()->insertId($this);
    }

    /**
     *  按ID查找对象
     * @param Application_Model_DomainObject $id 对象ID
     */
    public function find($id) {

        return $this->getDbTable()->getById($id);
    }

    /**
     * 返回第一个满足条件的对象
     * @param array $where
     * @return Application_Model_DomainObject
     */
    public function queryOne(array $where) {
        return $this->getDbTable()->queryOne($where);
    }

    /**
     * 返回所有满足条件的对象
     * @param array $where 条件数组
     * @param string $orderBy 排序
     * @return array
     */
    public function queryAll(array $where, $orderBy) {
//          var_dump($where);exit;
        return $this->getDbTable()->queryAll($where, $orderBy);
    }

    /**
     * 返回所有数据
     */
    public static function getAll() {
        return self::getDao()->queryAll();
    }

    /**
     * 删除当前对象
     */
    public function delete() {
        $this->getDbTable()->del(array('id' => $this->Id));
    }

    /**
     * 删除数据
    */
    public function deleteAll($condition = array())
    {
        if(!is_array($condition) || empty($condition)){
            return false;
        }
        $this->getDbTable()->del($condition);
    }

    /**
     * 根据ID重建持久化对象
     * @param type $id
     * @return Application_Model_DomainObject
     */
    public static function load($id) {
        $class = get_called_class();
        $tableName = str_replace('Application_Model_', 'Application_Model_DbTable_', $class);
        $db = new $tableName;
        return $db->getById($id);
    }

    /**
     * 返回数据库对象
     * @return Application_Model_DbTable_DomainObject
     */
    protected static function getDao() {
        $class = get_called_class();
        $tableName = str_replace('Application_Model_', 'Application_Model_DbTable_', $class);
        $db = new $tableName;
        return $db;
    }

    public function lcfirstex($string) {
        if (function_exists('lcfirst')) {
            return lcfirst($string);
        } else {
            if (!$string)
                return null;
            return preg_replace('/(^[A-Z])/', strtolower(substr($string, 0, 1)), $string);
        }
    }

    public function setData($key, $val = null) {
        $maps = self::getDao()->getMapper();
        if (is_array($key)) {
            foreach ($key as $_key => $_val) {
                if (in_array($_key, $maps)) {
                    $this->$_key = $_val;
                }
            }
        } else if (!is_null($val)) {
            if (in_array($_key, $maps)) {
                $this->$key = $val;
            }
        }
        return $this;
    }

}
